#include <QMutexLocker>
#include <numeric>
#include <algorithm>

#include "Library.h"

Library::Library() : books(0), readInterval(100),
  writeInterval(100), maxBooks(0), waitingWorkers(0) {
    books.reserve(maxBooks);
}

size_t Library::getLibSize() {
    QMutexLocker locker(&libMutex);
    return books.size();
}

QSharedPointer<QMutex> Library::getBook(size_t index) {
    libMutex.lock();
    QSharedPointer<QMutex> book = books[index];
    libMutex.unlock();
    if (!book->tryLock()) {
        waitingWorkers++;
emit awaitingUpdate(waitingWorkers);
        book->lock();
        waitingWorkers--;
emit awaitingUpdate(waitingWorkers);
    }

    return book;
}

void Library::returnBook(QSharedPointer<QMutex> book) {
    book->unlock();
}

int Library::add() {
    if (isFull()) return -1;
    QMutexLocker locker(&libMutex);
    size_t index = books.size();
    books.append( QSharedPointer<QMutex>(new QMutex()));
    emit numberOfBooksChanged(books.size());
    return index;
}

size_t Library::getReaderInterval() { return readInterval; }
size_t Library::getWriterInterval() { return writeInterval; }
void Library::setReaderInterval(int interval) { readInterval = interval; }
void Library::setWriterInterval(int interval) { writeInterval = interval; }

bool Library::isFull() { return books.size() == maxBooks; }

void Library::updateMaxBooks(int maxCount) {
    QMutexLocker locker(&libMutex);
    maxBooks = maxCount;
    if (static_cast<size_t>(books.size()) <= maxBooks)
        books.reserve(maxBooks);
    else
        books.resize(maxBooks);
emit numberOfBooksChanged(books.size());
}

